package com.flashidea.zddziot.view;

import java.math.BigDecimal;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.*;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.flashidea.zddziot.R;

/*- 在res->values资源文件中创建一个名为attrs的xml文件，使用自定义属性时要在布局中加入
 * “xmlns:环境名="http://schemas.android.com/apk/res/包名"”
 环境名:progressColor=""
 该文件内容如下：
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
 <declare-styleable name="CustomView">
 <!-- progressColor:进度颜色,默认 RED -->
 <attr name="progressColor" format="color|reference" />
 <!-- secondaryProgressColor:进度底层颜色,默认 BLUE -->
 <attr name="secondaryProgressColor" format="color|reference" />
 <!-- exceptProgressColor:进度以外的颜色,默认 GREEN -->
 <attr name="exceptProgressColor" format="color|reference" />
 <!-- scaleColor:刻度颜色,默认 BLACK -->
 <attr name="scaleColor" format="color|reference" />
 <!-- progressDrawable:进度图标按钮 -->
 <attr name="progressDrawable" format="reference" />
 <!-- max:最大进度,默认 100 -->
 <attr name="max" format="integer" />
 <!-- progress:当前进度,默认 50 -->
 <attr name="progress" format="integer" />
 <!-- size:进度条的大小,默认 10 -->
 <attr name="size" format="dimension|reference" />
 <!-- textSize:显示进度字体的大小,默认 20 -->
 <attr name="textSize" format="dimension|reference" />
 </declare-styleable>
 </resources>
 */
/**
 * 自定义圆弧形拖动条，支持xml布局修改属性
 * 
 * @author jinhui
 *
 */
public class SmileSeekBarView extends View {

	/**
	 * 滑动的图标
	 */
	private Bitmap thumb;
	/**
	 * 当前进度
	 */
	private int mProgress;
	/**
	 * 最大进度
	 */
	private float max = 100;
	/**
	 * 进度的颜色
	 */
	private int progressColor;
	/**
	 * 进度底层的颜色
	 */
	private int secondaryProgressColor;
	/**
	 * 进度以外的颜色
	 */
	private int mExceptProgressColor;
	/**
	 * 画笔
	 */
	private Paint paint;
	/**
	 * 圆半径
	 */
	private int radius;
	/**
	 * 拖动按钮的半径
	 */
	private float itemRadius;
	/**
	 * 圆心x坐标
	 */
	private float cx;
	/**
	 * 圆心y坐标
	 */
	private float cy;
	/**
	 * 当前滑块x坐标
	 */
	private float coordX;
	/**
	 * 当前滑块y坐标
	 */
	private float coordY;
	/**
	 * 进度条的大小
	 */
	private float size;
	/**
	 * 显示进度字体的大小
	 */
	private float textSize;
	/**
	 * 进度条占屏幕的宽度
	 */
	private int width;
	/**
	 * 拖动按钮最大角度
	 */
	private double maxDegree;
	/**
	 * 拖动按钮最小角度
	 */
	private double minDegree;
	/**
	 * 移动开始角度
	 */
	private double startAngle;
	/**
	 * 移动的角度
	 */
	private double angle;
	/**
	 * 监听器
	 */
	private OnProgressChangeListener listener;
	/**
	 * 右边文字
	 */
	private String rightText = "";
	/**
	 * 左边文字
	 */
	private String leftText = "";
	/**
	 * 是否可以拖动
	 */
	private boolean isTouch;

	/**
	 * 判断是否可以拖动
	 */
	public boolean isTouch() {
		return isTouch;
	}

	/**
	 * 设置是否可以拖动
	 * 
	 * @param isTouch
	 */
	public void setTouch(boolean isTouch) {
		this.isTouch = isTouch;
	}

	/**
	 * 获取右边文字
	 */
	public String getRightText() {
		return rightText;
	}

	/**
	 * 设置右边文字
	 */
	public void setRightText(String rightText) {
		this.rightText = rightText;
		invalidate();
	}

	/**
	 * 获取左边文字
	 */
	public String getLeftText() {
		return leftText;
	}

	/**
	 * 设置左边文字
	 */
	public void setLeftText(String leftText) {
		this.leftText = leftText;
		invalidate();
	}

	/**
	 * 获取进度条当前进度
	 */
	public int getProgress() {
		return mProgress;
	}

	/**
	 * 设置进度条当前进度
	 * 
	 * @param progress
	 *            进度百分数 0-100
	 */
	public void setProgress(int progress) {
		if (progress < 0) {
			progress = 0;
		} else if (progress > 100) {
			progress = 100;
		}
		mProgress = progress;
		angle = maxDegree - mProgress / 100f * (maxDegree - minDegree);
		invalidate();
	}

	/**
	 * 获取进度条最大进度
	 */
	public float getMax() {
		return max;
	}

	/**
	 * 设置进度条最大进度
	 */
	public void setMax(float max) {
		this.max = max;
	}

	/**
	 * 获取进度条一级进度颜色
	 */
	public int getProgressColor() {
		return progressColor;
	}

	/**
	 * 设置进度条一级进度颜色
	 */
	public void setProgressColor(int progressColor) {
		this.progressColor = progressColor;
	}

	/**
	 * 获取进度条二级进度颜色
	 */
	public int getSecondaryProgressColor() {
		return secondaryProgressColor;
	}

	/**
	 * 设置进度条二级进度颜色
	 */
	public void setSecondaryProgressColor(int secondaryProgressColor) {
		this.secondaryProgressColor = secondaryProgressColor;
	}

	/**
	 * 获取进度条上多出部分的颜色
	 */
	public int getExceptProgressColor() {
		return mExceptProgressColor;
	}

	/**
	 * 设置进度条上多出部分的颜色
	 */
	public void setExceptProgressColor(int exceptProgressColor) {
		this.mExceptProgressColor = exceptProgressColor;
	}

	/**
	 * 获取拖动条的大小
	 */
	public float getSize() {
		return size;
	}

	/**
	 * 设置拖动条的大小
	 */
	public void setSize(float size) {
		this.size = size;
	}

	/**
	 * 获取显示进度字体的大小
	 */
	public float getTextSize() {
		return textSize;
	}

	/**
	 * 设置显示进度字体的大小
	 */
	public void setTextSize(float textSize) {
		this.textSize = textSize;
		invalidate();
	}

	public SmileSeekBarView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context, attrs);
	}

	public SmileSeekBarView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init(context, attrs);
	}

	public SmileSeekBarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
		super(context, attrs, defStyleAttr, defStyleRes);
		init(context, attrs);
	}

	private void init(Context context, AttributeSet attrs) {
		/* 这里取得declare-styleable集合 */
		TypedArray typeArray = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
		/* 这里从集合里取出相对应的属性值,第二参数是如果使用者没用配置该属性时所用的默认值 */
		progressColor = typeArray.getColor(R.styleable.CustomView_progressColor, Color.RED);
		secondaryProgressColor = typeArray.getColor(R.styleable.CustomView_secondaryProgressColor,
			Color.BLUE);
		mExceptProgressColor = typeArray.getColor(R.styleable.CustomView_exceptProgressColor,
			Color.GREEN);
//		max = typeArray.getInt(R.styleable.CustomView_max, 100);
		mProgress = typeArray.getInt(R.styleable.CustomView_progress, 0);
		size = typeArray.getDimension(R.styleable.CustomView_size, 10f);
		textSize = typeArray.getDimension(R.styleable.CustomView_textSize, 10f);
		thumb = BitmapFactory.decodeResource(getResources(),
			typeArray.getResourceId(R.styleable.CustomView_progressDrawable, R.drawable.circle));
		/* 关闭资源 */
		typeArray.recycle();
		paint = new Paint();
		paint.setStrokeWidth(size);// 设置边的大小
		paint.setStyle(Paint.Style.STROKE);// 设置空心
		paint.setAntiAlias(true);// 去锯齿
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		width = MeasureSpec.getSize(getMeasuredWidth());
		// 求圆心在x=(getWidth()/2,0)上，经过(0,0)、(getWidth(),0)的圆半径
		radius = (int) (Math.sqrt(2) * (width / 2f));
		radius = width - radius / 5;
		cx = width / 2f;// 圆心的x坐标
		// 圆心的y坐标
		cy = (float) -Math.sqrt(radius * radius - (width / 2f) * (width / 2f));
		if (thumb != null) {
			setMeasuredDimension(getMeasuredWidth(), (int) (radius + cy + thumb.getHeight() / 3f
				* 2f + size / 2));
			itemRadius = Math.max(thumb.getWidth() / 2f, thumb.getHeight() / 2f);
			maxDegree = computeCurrentAngle(thumb.getWidth() + size / 2, thumb.getHeight() + size
				/ 2);
			minDegree = computeCurrentAngle(getWidth() - thumb.getWidth() - size / 2,
				thumb.getHeight() + size / 2);
		} else {
			setMeasuredDimension(getMeasuredWidth(), (int) (radius + cy + size / 2));
			maxDegree = computeCurrentAngle(0, size / 2);
			minDegree = computeCurrentAngle(getWidth(), size / 2);
		}
		angle = maxDegree - mProgress / 100f * (maxDegree - minDegree);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(mExceptProgressColor);
		canvas.drawCircle(cx, cy, radius, paint);
		computeCoordinates();
		drawProgressCircle(canvas);
		drawSecondaryCircle(canvas);
		computeProgress();
		drawProgressText(canvas);
		drawBitmap(canvas);
	}

	/**
	 * 计算当前进度的百分数
	 */
	private void computeProgress() {
		int progress = Integer.parseInt(new BigDecimal((maxDegree - angle)
			/ (maxDegree - minDegree) * 100).setScale(0, BigDecimal.ROUND_HALF_UP).toString());
		if (progress < 0) {
			progress = 0;
		} else if (progress > 100) {
			progress = 100;
		}
		mProgress = progress;
		if (listener != null) {
			listener.progressChange(this, mProgress);
		}
	}

	/**
	 * 画进度显示文字
	 */
	private void drawProgressText(Canvas canvas) {
		Paint paint = new Paint();
		paint.setTextSize(textSize);
		paint.setColor(Color.WHITE);
		paint.setAntiAlias(true);
		float[] textWidths = new float[leftText.length()];
		paint.getTextWidths(leftText, textWidths);
		int textWidth = 0;
		for (float f : textWidths) {
			textWidth += f;
		}
		canvas.drawText(leftText, thumb.getWidth() + size / 2, paint.getTextSize(), paint);
		textWidths = new float[rightText.length()];
		paint.getTextWidths(rightText, textWidths);
		textWidth = 0;
		for (float f : textWidths) {
			textWidth += f;
		}
		canvas.drawText(rightText, getWidth() - thumb.getWidth() - size / 2 - textWidth,
			paint.getTextSize(), paint);
	}

	/**
	 * 画二级进度
	 */
	private void drawSecondaryCircle(Canvas canvas) {
		canvas.save();
		Path path = new Path();
		if (thumb == null) {
			path.addRect(new RectF(coordX, 0, width, getHeight()), Path.Direction.CW);
		} else {
			path.addRect(new RectF(coordX, thumb.getHeight() / 2, width - thumb.getWidth() / 2f
				- size / 2, getHeight()), Path.Direction.CW);
		}
		canvas.clipPath(path); // 裁剪区域
		paint.setColor(secondaryProgressColor);
		canvas.drawCircle(cx, cy, radius, paint);
		canvas.restore();
	}

	/**
	 * 画当前进度
	 */
	private void drawProgressCircle(Canvas canvas) {
		canvas.save();
		Path path = new Path();
		if (thumb == null) {
			path.addRect(new RectF(0, 0, coordX, getHeight()), Path.Direction.CW);
		} else {
			path.addRect(new RectF(thumb.getWidth() / 2 + size / 2, thumb.getHeight() / 2, coordX,
					getHeight()), Path.Direction.CW);
		}
		canvas.clipPath(path); // 裁剪区域
		paint.setColor(progressColor);
		canvas.drawCircle(cx, cy, radius, paint);
		canvas.restore();
	}

	/**
	 * 画拖动按钮
	 */
	private void drawBitmap(Canvas canvas) {
		if (thumb == null) {
			return;
		}
		paint.setAlpha(255);
		Rect dst = new Rect();
		dst.left = (int) (coordX - itemRadius - paint.getStrokeWidth());
		dst.right = (int) (coordX + itemRadius + paint.getStrokeWidth());
		dst.top = (int) (coordY - itemRadius - paint.getStrokeWidth());
		dst.bottom = (int) (coordY + itemRadius + paint.getStrokeWidth());
		canvas.drawBitmap(thumb, null, dst, paint);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (!isTouch) {
			return true;
		}
		float x, y;
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			x = event.getX();
			y = event.getY();
			if (((x - cx) * (x - cx) + (y - cy) * (y - cy)) > Math.pow(radius + itemRadius * 2, 2)
				|| ((x - cx) * (x - cx) + (y - cy) * (y - cy)) < Math.pow(radius - itemRadius * 2,
					2)) {
				return false;
			}
			startAngle = computeCurrentAngle(x, y);
			rotateButtons(angle - startAngle);
		} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
			x = event.getX();
			y = event.getY();
			if (((x - cx) * (x - cx) + (y - cy) * (y - cy)) > Math.pow(radius + itemRadius * 2, 2)
				|| ((x - cx) * (x - cx) + (y - cy) * (y - cy)) < Math.pow(radius - itemRadius * 2,
					2)) {
				return false;
			}
			double currentAngle = computeCurrentAngle(x, y);
			rotateButtons(startAngle - currentAngle);
			startAngle = currentAngle;
		} else if (event.getAction() == MotionEvent.ACTION_UP) {
			x = (int) event.getX();
			y = (int) event.getY();
		}
		return true;
	}

	/**
	 * 移动按钮
	 */
	private void rotateButtons(double degree) {
		angle -= degree;
		if (angle < minDegree) {
			angle = minDegree;
		} else if (angle > maxDegree) {
			angle = maxDegree;
		}
		invalidate();
	}

	/**
	 * 计算拖动按钮中心坐标
	 */
	private void computeCoordinates() {
		coordX = cx + (float) (radius * Math.cos(Math.toRadians(angle)));
		coordY = cy + (float) (radius * Math.sin(Math.toRadians(angle)));
	}

	/**
	 * 计算某点的角度
	 * 
	 * @param x
	 * @param y
	 */
	private double computeCurrentAngle(float x, float y) {
		float distance = (float) Math.sqrt(((x - cx) * (x - cx) + (y - cy) * (y - cy)));
		double degree = Math.acos((x - cx) / distance) * 180 / Math.PI;
		if (y < cy) {
			degree = -degree;
		}
		return degree;
	}

	/**
	 * 设置进度变化监听
	 * 
	 * @param listener
	 */
	public void setOnProgressChangeListener(OnProgressChangeListener listener) {
		if (isTouch) {
			this.listener = listener;
		}
	}

	/**
	 * 进度变化监听接口
	 * 
	 * @author jinhui
	 */
	public interface OnProgressChangeListener {

		/**
		 * 进度变化监听回调函数
		 * 
		 * @param view
		 * @param progress
		 *            当前进度 0%-100%
		 */
		public void progressChange(View view, int progress);
	}
}
